package server;

import java.util.Stack;

public class NodeInfo {
	private Object lock = new Object();
	private String nodeName; 
	private String IP;
	private Integer port; 
	private String dbName; 
	private String user; 
	private String password;
	private String OS;
	private int priority;
	private UpdateXid failedXid;
	private UpdateFailureType updateFailureType;
	private boolean connected;
	private boolean attached;
	private Stack<String> missedNonqueries;
	
	public NodeInfo(String args[]) {	
		this.nodeName = args[0];
		this.IP = args[1];
		this.port = Integer.parseInt(args[2]);
		this.dbName = args[3];
		this.user = args[4];
		this.password = args[5];
		
		if (args.length == 8) {
			this.failedXid = new UpdateXid(Byte.parseByte(args[6]));
			this.updateFailureType = 
				args[7].equalsIgnoreCase("COMMIT") ? UpdateFailureType.Commit 
												   : UpdateFailureType.Rollback;
		} else {
			this.failedXid = null;
		}
		
		this.missedNonqueries = new Stack<String>();
	}

	public String getUrl(){
		String url = "jdbc:postgresql://" + IP;	
		
		if(port != null)
			url += ":" + port;
		
		url += "/" + dbName;
		return url;
	}
	
	@Override
	public String toString(){
		return nodeName + "$" + IP + "$" + port + "$" + dbName + "$" + user + "$" + password;
	}

	public void setIP(String iP) {
		IP = iP;
	}

	public String getIP() {
		return IP;
	}

	public void setPort(Integer port) {
		this.port = port;
	}

	public Integer getPort() {
		return port;
	}

	public void setDbName(String dbName) {
		this.dbName = dbName;
	}

	public String getDbName() {
		return dbName;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getUser() {
		return user;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPassword() {
		return password;
	}

	public void setOS(String oS) {
		OS = oS;
	}

	public String getOS() {
		return OS;
	}

	public void setNodeName(String nodeName) {
		this.nodeName = nodeName;
	}

	public String getNodeName() {
		return nodeName;
	}

	public void setPriority(int priority) {
		this.priority = priority;
	}

	public int getPriority() {
		return priority;
	}

	public String getStatus() {
		if(isUpdateFailed())
			return "Wezel posiada wiszaca transakcje.";
		else
			return "OK";
	}

	public void updateFailured(UpdateXid xid, UpdateFailureType type) {
		this.failedXid = xid;
		this.updateFailureType = type;
	}

	public boolean isUpdateFailed() {
		return failedXid != null;
	}

	public UpdateXid getFailedXid() {
		return failedXid;
	}

	public UpdateFailureType getFailedOperation() {
		return updateFailureType;
	}	

	public void updateRecovered(){
		this.failedXid = null;
		this.updateFailureType = null;
	}

	public void setConnected(boolean connected) {
		synchronized(lock){
			this.connected = connected;
			if(connected == false)
				this.attached = false;
		}
	}

	public boolean isConnected() {
		synchronized(lock){
			return connected;
		}
	}

	public void setAttached(boolean attached) {
		synchronized(lock){
			this.attached = attached;
			if(attached)
				this.connected = true;
		}
	}

	public boolean isAttached() {
		synchronized(lock){
			return attached;
		}
	}

	public Stack<String> getMissedNonQueries() {
		return this.missedNonqueries;
	}
	
	public void pushMissedNonQuery(String nonquery){
		this.missedNonqueries.push(nonquery);
	}
		
}
